#在函数内部声明的函数，且访问外层函数作用域的变量，作为外层函数返回值返回的函数就称为闭包函数
#用于函数之间的通信交互  可用通过内层函数访问外层函数中的全局变量
# 在函数内部声明的函数，且访问外层函数作用域的变量，作为外层函数返回值返回的函数就称为闭包函数：解释闭包函数的定义。
# 用于函数之间的通信交互 可用通过内层函数访问外层函数中的局部变量：说明闭包函数的用途。
#warper 函数
def warper():      #定义名为 warper 的函数。
    num = 10       #在 warper 函数内部定义局部变量 num 并赋值为 10 。
    def inner():   #在 warper 函数内部定义嵌套函数 inner ，这是闭包函数的内层函数。
        nonlocal num #声明 inner 函数中使用的 num 不是局部变量，而是引用外层函数（warper 函数）的局部变量。
        num += 1     #对引用的外层函数变量 num 进行加 1 操作。
    return inner    #warper 函数返回内层函数 inner ，此时 inner 成为闭包函数，它能记住并操作外层函数 warper 中的 num 变量 。

# # 预防变量污染
# def fn1():    定义函数 fn
#     a = 10    在 fn1 函数内部原本要定义局部变量 a 并赋值为 10

#fn 函数
def fn():       #定义名为 fn 的函数。
    a = 10      #在 fn 函数内部定义局部变量 a 并赋值为 10 。
    def setA(val):   #在 fn 函数内部定义嵌套函数 setA ，用于修改外层函数 fn 中的变量 a 。
        nonlocal a    #声明 setA 函数中使用的 a 不是局部变量，而是引用外层函数（fn 函数）的局部变量。
        a = val     #将外层函数的变量 a 的值修改为传入的参数 val 。
    def getA():     #在 fn 函数内部定义嵌套函数 getA ，用于获取外层函数 fn 中的变量 a 的值。
        nonlocal a    #声明 getA 函数中使用的 a 不是局部变量，而是引用外层函数（fn 函数）的局部变量。
        return a    #返回外层函数 fn 中变量 a 的值。
    return setA, getA     #fn 函数返回两个内部函数 setA 和 getA ，形成闭包。


#函数调用及操作部分
tupleFn = fn()    #调用 fn 函数，返回包含 setA 和 getA 两个函数的元组，并赋值给 tupleFn 。
setA = tupleFn[0]   #从元组 tupleFn 中取出第一个函数（setA 函数），并赋值给变量 setA 。
getA = tupleFn[1]    #从元组 tupleFn 中取出第二个函数（getA 函数），并赋值给变量 getA 。
setA(11)       #调用 setA 函数，将外层函数 fn 中的变量 a 的值修改为 11 。
print(getA())   #调用 getA 函数，获取并打印外层函数 fn 中变量 a 的值（此时值为 11 ）。






